﻿using MediatR;
using Newtonsoft.Json;
using WorkflowCore.Interface;
using WorkflowCore.Models.DefinitionStorage.v1;
using WorkflowCore.Services.DefinitionStorage;
using Yitter.IdGenerator;
using Yuekao.API.Write.Command;
using Yuekao.Domain.API;
using Yuekao.Domain.BaseReposi;
using Yuekao.Domain.Entitys;
using Yuekao.Domain.Step;

namespace Yuekao.API.Write.CommandHander
{
    public class DefinitionAddCommandHandler : IRequestHandler<DefinitionAddCommand, APIResult<int>>
    {
        private readonly IBaseRepository<WorkflowDefinitionModel> _repository;
        private readonly IWorkflowRegistry _host;
        private readonly IDefinitionLoader _definitionLoader;
        public DefinitionAddCommandHandler(IBaseRepository<WorkflowDefinitionModel> repository, IDefinitionLoader definitionLoader, IWorkflowRegistry host)
        {
            _repository = repository;
            _definitionLoader = definitionLoader;
            _host = host;
        }
        public Task<APIResult<int>> Handle(DefinitionAddCommand request, CancellationToken cancellationToken)
        {
            APIResult<int> result=new APIResult<int>();

            var list = _repository.GetValues(x=>x.DefinitionId==request.DefinitionId&&x.Version==request.Version);
            //if (list!=null)
            //{
            //    result.Code = APIEnum.Fail;
            //    result.Message = "流程设计已存在";
            //    return Task.FromResult(result);
            //}
            WorkflowDefinitionModel model=new WorkflowDefinitionModel();
            model.Id = YitIdHelper.NextId();
            model.Version=request.Version;
            model.DefinitionId = request.DefinitionId;
            model.CreateName = request.CreateName;
            model.Title=request.Title;
            model.Steps=JsonConvert.SerializeObject(request.Steps);
            model.CreateTime=DateTime.Now;
            _repository.Add(model);

            Location(model);

            result.Code = APIEnum.Success;
            result.Message = "流程设计新增成功";
            result.Data = 1;
            return Task.FromResult(result);
        }
        /// <summary>
        /// 流程加载
        /// </summary>
        /// <param name="model">流程设计实体</param>
        public void Location(WorkflowDefinitionModel model)
        {
            if(_host.IsRegistered(model.DefinitionId,model.Version))
            {
                return;
            }

            DefinitionSourceV1 source = new DefinitionSourceV1()
            { 
                Id=model.DefinitionId,
                Version=model.Version,
                Description=model.Title,
                DataType=$"{typeof(Dictionary<string,object>).FullName},{typeof(Dictionary<string, object>).Assembly.FullName}"
            };

            var list =JsonConvert.DeserializeObject<List<StepNode>>(model.Steps);

            StepSourceV1 startStep = new StepSourceV1()
            {
                Id=nameof(StartStep),
                Name="开始",
                StepType= $"{typeof(StartStep).FullName},{typeof(StartStep).Assembly.FullName}",
                NextStepId= list.First().StepId
            };
            source.Steps.Add(startStep);


            foreach (var item in list)
            {
                StepSourceV1 auditStep = new StepSourceV1()
                {
                    Id = item.StepId,
                    Name = item.StepName,
                    StepType = $"{typeof(AuditStep).FullName},{typeof(AuditStep).Assembly.FullName}",
                    NextStepId = item.NextStep
                };
                auditStep.Inputs.TryAdd("AuditId",$"\"{item.AuditId}\"");
                auditStep.Inputs.TryAdd("AuditName", $"\"{item.AuditName}\"");
                source.Steps.Add(auditStep);
            }
            
            StepSourceV1 endStep = new StepSourceV1()
            {
                Id = nameof(EndStep),
                Name = "结束",
                StepType = $"{typeof(EndStep).FullName},{typeof(EndStep).Assembly.FullName}",
            };
            source.Steps.Add(endStep);

            var json=JsonConvert.SerializeObject(source);
            _definitionLoader.LoadDefinition(json,Deserializers.Json);
        }
    }
}
